package net.dodoman;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Jzzh {
	// *****************************任意进制到十进制的转换*****************************
	// 任意进制到十进制的转换

	String anySystemToTen(double longNum) throws Exception {
		String strNum = String.valueOf(longNum);
		// 将取得的整数部份和小数部份的进制结合在一起，并将其还原为浮点数
		// strNum=intToTenSystem(strInt,JZ)+"."+lessToTenSystem(strLess,JZ);
		return strNum;
	}

	// 保证输入的数与进制相配

	boolean checkInputNumIsOK(int Num, int jz) {
		if (Num <= jz - 1)
			return true;
		else
			return false;
	}

	// 由取最得的字符返回相应的数字

	String letterToInteger(String tChar) {
		int gotNum = 0;
		int kg = 0; // 确定前面该字符是不是已经赋值，这就是使用if语句所留下的后症
		String S;
		if (tChar.equals("A")) {
			gotNum = 10;
			kg = 1;
		} else if (tChar.equals("B")) {
			gotNum = 11;
			kg = 1;
		} else if (tChar.equals("C")) {
			gotNum = 12;
			kg = 1;
		} else if (tChar.equals("D")) {
			gotNum = 13;
			kg = 1;
		} else if (tChar.equals("E")) {
			gotNum = 14;
			kg = 1;
		} else if (tChar.equals("F")) {
			gotNum = 15;
			kg = 1;
		} else if (tChar.equals("G")) {
			gotNum = 16;
			kg = 1;
		} else if (tChar.equals("H")) {
			gotNum = 17;
			kg = 1;
		} else if (tChar.equals("I")) {
			gotNum = 18;
			kg = 1;
		} else if (tChar.equals("J")) {
			gotNum = 19;
			kg = 1;
		} else if (tChar.equals("K")) {
			gotNum = 20;
			kg = 1;
		} else if (tChar.equals("L")) {
			gotNum = 21;
			kg = 1;
		} else if (tChar.equals("M")) {
			gotNum = 22;
			kg = 1;
		} else if (tChar.equals("O")) {
			gotNum = 23;
			kg = 1;
		} else if (tChar.equals("P")) {
			gotNum = 24;
			kg = 1;
		} else if (tChar.equals("Q")) {
			gotNum = 25;
			kg = 1;
		} else if (tChar.equals("R")) {
			gotNum = 26;
			kg = 1;
		} else if (tChar.equals("S")) {
			gotNum = 27;
			kg = 1;
		} else if (tChar.equals("T")) {
			gotNum = 28;
			kg = 1;
		} else if (tChar.equals("U")) {
			gotNum = 29;
			kg = 1;
		} else if (tChar.equals("V")) {
			gotNum = 30;
			kg = 1;
		} else if (tChar.equals("W")) {
			gotNum = 31;
			kg = 1;
		} else if (tChar.equals("X")) {
			gotNum = 32;
			kg = 1;
		} else if (tChar.equals("Y")) {
			gotNum = 33;
			kg = 1;
		} else if (tChar.equals("Z")) {
			gotNum = 34;
			kg = 1;
		} else if (kg == 0) {
			gotNum = Integer.parseInt(tChar);
		}
		S = String.valueOf(gotNum);
		return S;
	}

	// 浮点数的整数部份转换为十进制

	String intToTenSystem(String strNum, int jz) throws Exception {
		strNum = strNum.toUpperCase(); // 全部转换为大写，方便字符到数字的转换
		double longNum = 0;
		int len = strNum.length(); // 取得字符串的长度
		int tInt = 0; // 初使化数组位置为0
		int gotNum = 0; // 一个一个字符取出所对应的数字
		while (len > 0) { // 如果没有将字符串的字符转换完，就继续
			String tChar = strNum.substring(tInt, tInt + 1); // 一个一个字符的取
			gotNum = Integer.parseInt(letterToInteger(tChar));
			if (!checkInputNumIsOK(gotNum, jz)) {
				System.out.println("你的输入与转换的进制不符，请检查！");
				System.exit(-1);
			}

			longNum = longNum + gotNum * (Math.pow(jz, len - 1));
			tInt++;
			len--;

		}
		return String.valueOf(longNum);
	}

	// 浮点数小数部份转换为十进制

	String lessToTenSystem(String strNum, int jz) throws Exception {
		strNum = strNum.toUpperCase();
		double longNum = 0;
		int len = strNum.length(); // 取得字符的长度
		int tInt = 0; // 取第tInt个字符
		int gotNum = 0; // 取出的字符转换为数字
		int cfInt = -1; // 多少次次方
		while (len > 0) {
			String tChar = strNum.substring(tInt, tInt + 1); // 一个一个字符的取
			gotNum = Integer.parseInt(letterToInteger(tChar));
			if (!checkInputNumIsOK(gotNum, jz)) {
				System.out.println("你的输入与转换的进制不符，请检查！");
				System.exit(-1);
			}
			// 保存出小数部份从对应的进制到十进制的总值
			longNum = longNum + gotNum * (Math.pow(jz, cfInt)); // 关键算法
			tInt++; // 字符串中位置加一
			len--; // 字符串总长度减一
			cfInt--;
		}
		return String.valueOf(longNum);
	}

	// 返回一个浮点数的整数或者是小数部份

	String returnWantPart(String doubleNum, String whichPart) throws Exception {
		String strNum = doubleNum;
		String leftStr;
		String rightStr;
		// 如果输入的是一个浮点数
		if (strNum.indexOf(".") != -1) {
			StringTokenizer fenxi = new StringTokenizer(strNum, ".");
			leftStr = fenxi.nextToken();
			rightStr = fenxi.nextToken();
		} else { // 如果输入的是一个整数
			leftStr = strNum;
			rightStr = "0";
		}
		String returnStr = "";
		if (whichPart.equals("left"))
			returnStr = leftStr;
		else if (whichPart.equals("right"))
			returnStr = rightStr;
		return returnStr;
	}

	// *****************************任意进制到十进制的转换*****************************
	// *****************************十进制到任意进制的转换*****************************

	String tenToAnySystem_Int(String strInt, int jz) { // 因为由任意进制到十进制的转换结果为"整数部分.小数部份"
		// 也就是分成整数和小数部份分别转换
		// 此函数完成的功能是十进制的整数部分到任意进制的转换
		try {
			// 取出整数部份
			strInt = returnWantPart(strInt, "left");
		} catch (Exception e) {
			e.printStackTrace();
		}
		long intStr = Long.parseLong(strInt);
		long[] result = new long[50]; // 用50个数组来保存相除的余数
		long T;
		String resultStr = "";
		int i = 0; // 数组的下标
		while (intStr != 0) {
			result[i] = intStr % jz; // 取出余数
			intStr = intStr - result[i]; // 现数为减去余数的数
			intStr = intStr / jz;
			i++; // 数组下标增加一
		}
		// 将数组全部反序排列,并返回结果
		for (int j1 = 0, j2 = i - 1; j1 < (i / 2); j1++, j2--) {
			T = result[j1];
			result[j1] = result[j2];
			result[j2] = T;
		}
		for (int j = 0; j < i; j++) {
			resultStr = resultStr + intToLetter(result[j]);

		}
		return resultStr;

	}

	// 此函数完成的功能是十进制的小数部分到任意进制的转换

	String tenToAnySystem_Less(String strLess, int jz) {
		double T = 0;
		T = Double.parseDouble(strLess);
		String resultStr = "";
		String strInt = "";
		// 精度取到小数点后面6位为止
		int JinDu = 0;
		int i = 0; // 数组下标
		int[] result = new int[50];
		for (int j = 0; j < 50; j++)
			// 将数组初使化
			result[j] = 0;
		try {
			while (JinDu <= 6 && T > 0.000001) {
				double tNum = 0;
				tNum = T * jz;
				if (tNum > 1) { // 取出整数部份
					try {
						strInt = returnWantPart(String.valueOf(tNum), "left");
					} catch (Exception e) {
						e.printStackTrace();
					}
					result[i] = Integer.parseInt(strInt);
					T = tNum - result[i]; // 将当前数减去取出来的数
				} else {
					// 如果整数小于零，那么整数部分就是0
					result[i] = 0;
				}
				JinDu++;
				i++;

			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		for (int j = 0; j < i; j++)
			resultStr = resultStr + String.valueOf(result[j]);
		if (i == 0)
			return "0";
		else
			return resultStr;

	}

	// 将取得的数字转换为相应的字母

	String intToLetter(long num) {
		String result = "";
		String S = "";
		if (0 <= num && num <= 9)
			result = String.valueOf(num);
		else if (num > 9) {
			S = String.valueOf(num); // 将长整型转换为字符串型
			switch (Integer.parseInt(S)) // 将字符串型转换为整型
			{
			case 10:
				result = "A";
				break;
			case 11:
				result = "B";
				break;
			case 12:
				result = "C";
				break;
			case 13:
				result = "D";
				break;
			case 14:
				result = "E";
				break;
			case 15:
				result = "F";
				break;
			case 16:
				result = "G";
				break;
			case 17:
				result = "H";
				break;
			case 18:
				result = "I";
				break;
			case 19:
				result = "G";
				break;
			case 20:
				result = "K";
				break;
			case 21:
				result = "L";
				break;
			case 22:
				result = "M";
				break;
			case 23:
				result = "N";
				break;
			case 24:
				result = "O";
				break;
			case 25:
				result = "P";
				break;
			case 26:
				result = "Q";
				break;
			case 27:
				result = "R";
				break;
			case 28:
				result = "S";
				break;
			case 29:
				result = "T";
				break;
			case 30:
				result = "U";
				break;
			case 31:
				result = "V";
				break;
			case 32:
				result = "W";
				break;
			case 33:
				result = "X";
				break;
			case 34:
				result = "Y";
				break;
			case 35:
				result = "Z";
				break;
			}
		}
		return result;
	}

	// *****************************十进制到任意进制的转换*****************************

	public static void main(String[] arg) throws Exception {
		try {
			Jzzh jzzh = new Jzzh();
			BufferedReader br = new BufferedReader(new InputStreamReader(
					System.in));
			String inData = " ";

			while (!inData.toUpperCase().equals("QUIT")) {
				System.out.print("请输入一个数(quit退出)(格式:原数,原数进制,要转换到的进制)：");
				inData = br.readLine();
				if (inData.equals("") || inData.equals(" "))
					continue;
				if (inData.toUpperCase().equals("QUIT"))
					break;
				StringTokenizer fenxi = new StringTokenizer(inData, ",");
				String tData = fenxi.nextToken(); // 取出原数
				// String whichPart=
				// System.out.println("The Result is :"+tData);
				int whichSystem = Integer.parseInt(fenxi.nextToken()); // 取出原进制
				int targetSystem = Integer.parseInt(fenxi.nextToken()); // 取出要转换的进制
				String returnLeftPart; // 输入数的整数部分
				String returnRightPart; // 输入数的小数部分
				// 分别取出数的左面和右面
				returnLeftPart = jzzh.returnWantPart(tData, "left"); // 取出输入数的整数部分
				returnRightPart = jzzh.returnWantPart(tData, "right"); // 取出输入数的小数部分

				String anyChangedToIntSystem; // 用于接收输入数的整数部分转换后的结果
				String anyChangedToLessSystem; // 用于接收输入数的小数部分转换后的结果
				anyChangedToIntSystem = jzzh.intToTenSystem(returnLeftPart,
						whichSystem);
				anyChangedToLessSystem = jzzh.lessToTenSystem(returnRightPart,
						whichSystem);

				double leftNum = Double.parseDouble(anyChangedToIntSystem);
				double rightNum = Double.parseDouble(anyChangedToLessSystem);
				double totalNum = leftNum + rightNum; // 拼合结果
				System.out.println(tData + "由" + whichSystem + "到10进制的结果是:"
						+ jzzh.anySystemToTen(totalNum));

				// 十进制到任意进制的转换temToAnySystem_Less
				String tenChangedToAnySystemInt = "";
				String tenChangedToAnySystemLess = "";
				tenChangedToAnySystemInt = jzzh.tenToAnySystem_Int(
						anyChangedToIntSystem, targetSystem);
				tenChangedToAnySystemLess = jzzh.tenToAnySystem_Less(
						anyChangedToLessSystem, targetSystem);
				System.out.println(tData + "由" + whichSystem + "到"
						+ targetSystem + "进制的结果是:" + tenChangedToAnySystemInt
						+ "." + tenChangedToAnySystemLess);

			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
